package com.task.scheduler.model;

import com.alibaba.fastjson.JSON;
import com.task.scheduler.enums.TaskExecutionMode;
import com.task.scheduler.executor.TaskExecutor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.function.BiConsumer;

/**
 * 泛化任务模型类（SDK对外暴露的任务结构）
 *
 * 示例用法：
 * GenericTask task = GenericTask.localTask()
 *     .taskType("HTTP")
 *     .jsonParams("{\"url\": \"http://api.example.com\"}")
 *     .executor((t) -> "{ \"code\": 0 }")
 *     .onSuccess((t, result) -> System.out.println("✅ 成功：" + result))
 *     .onFailure((t, e) -> System.err.println("❌ 失败：" + e.getMessage()))
 *     .build();
 */
@Slf4j
@Data
public class GenericTask implements Serializable {

    private String taskId;
    private String taskType;
    private String jsonParams;
    private int retryCount;
    private int maxRetry;
    private long delaySeconds;
    private TaskExecutor executor;
    private BiConsumer<GenericTask, String> onSuccess;
    private BiConsumer<GenericTask, Exception> onFailure;
    private TaskExecutionMode executionMode = TaskExecutionMode.REMOTE;
    private String lastErrorMessage;

    public GenericTask() {
        // 默认构造函数
    }

    public String toJson() {
        return JSON.toJSONString(this);
    }

    public static GenericTask fromJson(String json) {
        return JSON.parseObject(json, GenericTask.class);
    }

    /**
     * 构建本地任务（必须提供 executor）
     */
    public static LocalTaskBuilder localTask() {
        return new LocalTaskBuilder();
    }

    /**
     * 构建远程任务（不能提供 executor/onSuccess/onFailure）
     */
    public static RemoteTaskBuilder remoteTask() {
        return new RemoteTaskBuilder();
    }

    /**
     * 本地任务构建器（必须设置 executor）
     */
    public static class LocalTaskBuilder {
        private String taskId = java.util.UUID.randomUUID().toString();
        private String taskType;
        private String jsonParams;
        private int retryCount;
        private int maxRetry = 3;
        private long delaySeconds;
        private TaskExecutor executor;
        private BiConsumer<GenericTask, String> onSuccess;
        private BiConsumer<GenericTask, Exception> onFailure;

        public LocalTaskBuilder taskId(String taskId) {
            this.taskId = taskId;
            return this;
        }

        public LocalTaskBuilder taskType(String taskType) {
            this.taskType = taskType;
            return this;
        }

        public LocalTaskBuilder jsonParams(String jsonParams) {
            this.jsonParams = jsonParams;
            return this;
        }

        public LocalTaskBuilder maxRetry(int maxRetry) {
            this.maxRetry = maxRetry;
            return this;
        }

        public LocalTaskBuilder delaySeconds(long delaySeconds) {
            this.delaySeconds = delaySeconds;
            return this;
        }

        public LocalTaskBuilder executor(TaskExecutor executor) {
            this.executor = executor;
            return this;
        }

        public LocalTaskBuilder onSuccess(BiConsumer<GenericTask, String> onSuccess) {
            this.onSuccess = onSuccess;
            return this;
        }

        public LocalTaskBuilder onFailure(BiConsumer<GenericTask, Exception> onFailure) {
            this.onFailure = onFailure;
            return this;
        }

        public GenericTask build() {
            if (executor == null) {
                throw new IllegalStateException("本地任务必须指定 executor");
            }

            GenericTask task = new GenericTask();
            task.setTaskId(taskId);
            task.setTaskType(taskType);
            task.setJsonParams(jsonParams);
            task.setMaxRetry(maxRetry);
            task.setDelaySeconds(delaySeconds);
            task.setRetryCount(retryCount);
            task.setExecutor(executor);
            task.setOnSuccess(onSuccess);
            task.setOnFailure(onFailure);
            task.executionMode = TaskExecutionMode.LOCAL;

            log.info("💡 未指定执行器，SDK 将根据 taskType 自动匹配");
            return task;
        }
    }

    /**
     * 远程任务构建器（禁止设置 executor/onSuccess/onFailure）
     */
    public static class RemoteTaskBuilder {
        private String taskId = java.util.UUID.randomUUID().toString();
        private String taskType;
        private String jsonParams;
        private int retryCount;
        private int maxRetry = 3;
        private long delaySeconds;

        public RemoteTaskBuilder taskId(String taskId) {
            this.taskId = taskId;
            return this;
        }

        public RemoteTaskBuilder taskType(String taskType) {
            this.taskType = taskType;
            return this;
        }

        public RemoteTaskBuilder jsonParams(String jsonParams) {
            this.jsonParams = jsonParams;
            return this;
        }

        public RemoteTaskBuilder maxRetry(int maxRetry) {
            this.maxRetry = maxRetry;
            return this;
        }

        public RemoteTaskBuilder delaySeconds(long delaySeconds) {
            this.delaySeconds = delaySeconds;
            return this;
        }

        public GenericTask build() {
            GenericTask task = new GenericTask();
            task.setTaskId(taskId);
            task.setTaskType(taskType);
            task.setJsonParams(jsonParams);
            task.setMaxRetry(maxRetry);
            task.setDelaySeconds(delaySeconds);
            task.setRetryCount(retryCount);
            task.setExecutionMode(TaskExecutionMode.REMOTE);

            // 禁止设置这些字段
            task.setExecutor(null);
            task.setOnSuccess(null);
            task.setOnFailure(null);

            return task;
        }
    }

}
